﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using PSI.Helper;
using PSI.Models;
using System.Data;

namespace PSI.Services {
    /// <summary>
    /// 用户 Service
    /// </summary>
    public class UserService : PSIBaseService {
        private const string LOGIN_USER = "PSI_LOGIN_USER";

        public static bool IsLogin {
            get {
                return HttpContext.Current.Session[LOGIN_USER] != null;
            }
        }

        /// <summary>
        /// 把当前登录的用户对象保存到Seesion中
        /// </summary>
        /// <param name="user"></param>
        public static void SetLoginUser(User user) {
            HttpContext.Current.Session[LOGIN_USER] = user;
        }

        public static User GetLoginUser() {
            return HttpContext.Current.Session[LOGIN_USER] as User;
        }

        public static string GetLoginUserName() {
            var user = GetLoginUser();

            return user != null ? user.Name : string.Empty;
        }

        public void ClearLoginUser() {
            HttpContext.Current.Session[LOGIN_USER] = null;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public Result Login(User user) {
            if (user == null) {
                throw new ArgumentNullException("user");
            }

            var p = CreateDbParameters();
            p.AddWithValue("login", user.LoginName);
            p.AddWithValue("password", SimpleCrypt.Encode(user.Password));

            var sql = @"select count(*) from psi_user 
                        where login_name = @login and password = @password and enabled = 1";

            var count = QueryCount(sql, p);

            if (count != 1) {
                return new Result { Success = false, Messgae = "用户名或者密码错误" };
            } else {
                sql = "select user_id, user_name from psi_user where login_name = @login";

                p = CreateDbParameters();
                p.AddWithValue("login", user.LoginName);

                var u = QueryObject<User>(sql, p,
                    reader => {
                        return new User {
                            Id = reader.GetString(0),
                            Name = reader.GetString(1)
                        };
                    });

                u.LoginName = user.LoginName;
                u.Password = user.Password;

                SetLoginUser(u);

                // 记录日志
                new LogService().Log("登录系统");

                return new Result { Success = true };
            }
        }


        public List<User> GetUsers(string orgId) {
            var result = new List<User>();

            var sql = @"select user_id, login_name, user_name,tel ,enabled, org_code,org_id 
                        from psi_user where org_id = @orgId order by login_name";

            var db = DBHelper.AdoTemplate;

            var p = db.CreateDbParameters();
            p.AddWithValue("orgId", orgId);

            db.Query(sql, reader => {
                var u = new User {
                    Id = reader.GetString(0),
                    LoginName = reader.GetString(1),
                    Name = reader.GetString(2),
                    Tel = reader.GetString(3),
                    Enabled = reader.GetInt32(4) == 1,
                    OrgCode = reader.GetString(5),
                    OrgId = reader.GetString(6)
                };

                result.Add(u);
            }, p);

            return result;
        }

        public Result EditOrg(Models.Org org)
        {
            // TODO 组织机构的编码的校验还没有完成

            org.ParentId = org.ParentId ?? string.Empty;
            if (org.ParentId == "root") {
                org.ParentId = string.Empty;
            }

            var result = new Result { Success = true, Messgae = string.Empty };

            var parentFullName = string.Empty;
            var sql = string.Empty;
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();

            if (!string.IsNullOrEmpty(org.ParentId)) {
                sql = "select org_full_name from psi_org where org_id = @parentId";
                p.AddWithValue("parentId", org.ParentId);
                try {
                    parentFullName = db.QueryObject<string>(sql,
                        reader => {
                            return reader.GetString(0);
                        }, p);
                } catch {
                    parentFullName = string.Empty;
                }
            }

            if (string.IsNullOrEmpty(parentFullName)) {
                org.FullName = org.Name;
            } else {
                org.FullName = parentFullName + "\\" + org.Name;
            }

            if (string.IsNullOrEmpty(org.Id)) {
                // 新增
                org.Id = IdGeneratorService.NewId();
                sql = @"insert into psi_org(org_id, org_name, parent_id, org_code, org_full_name, can_delete)
                        values (@orgId, @orgName, @parentId, @orgCode, @fullName, @canDelete)";
                p = db.CreateDbParameters();
                p.AddWithValue("orgId", org.Id);
                p.AddWithValue("orgName", org.Name);
                p.AddWithValue("parentId", org.ParentId);
                p.AddWithValue("fullName", org.FullName);
                p.AddWithValue("orgCode", org.OrgCode);
                p.AddWithValue("canDelete", "0000000000"); // 十个0

                db.Execute(sql, p);

                // 记录操作日志
                new LogService().Log("新增组织机构：" + org.ToString());
            } else {
                if (org.Id == org.ParentId) {
                    return new Result { Success = false, Messgae = "上级组织不能是自身" };
                }

                sql = "select org_full_name from psi_org where org_id = @orgId";
                p = db.CreateDbParameters();
                p.AddWithValue("orgId", org.Id);
                var oldFullName = db.QueryObject<string>(sql,
                    reader => {
                        return reader.GetString(0);
                    }, p);

                // 判断当前的ParnetId不能是org的下级组织
                sql = "select org_id from psi_org where substring(org_full_name, 1, len(@fullName)) = @fullName";
                p = db.CreateDbParameters();
                p.AddWithValue("fullName", oldFullName);
                var subOrgsIdList = new List<string>();
                db.Query(sql, reader => {
                    subOrgsIdList.Add(reader.GetString(0));
                }, p);

                if (subOrgsIdList.IndexOf(org.ParentId) != -1) {
                    return new Result { Success = false, Messgae = "不能选择下级组织作为上级组织" };
                }

                // 编辑
                DBHelper.TransactionTemplate.WithTransaction(() => {
                    // 修改org本身
                    sql = @"update psi_org set org_name = @orgName, org_full_name = @orgFullName, 
                        parent_id = @parentId, org_code = @orgCode
                        where org_id = @orgId";
                    p = db.CreateDbParameters();
                    p.AddWithValue("orgId", org.Id);
                    p.AddWithValue("orgName", org.Name);
                    p.AddWithValue("parentId", org.ParentId);
                    p.AddWithValue("orgFullName", org.FullName);
                    p.AddWithValue("orgCode", org.OrgCode);
                    db.Execute(sql, p);

                    // 修改org的下级组织的FullName
                    sql = @"update psi_org set org_full_name = @newFullName + substring(org_full_name, len(@oldFullName) + 1, len(org_full_name)) 
                        where substring(org_full_name, 1, len(@oldFullName)) = @oldFullName
                                and org_id <> @orgId";
                    p = db.CreateDbParameters();
                    p.AddWithValue("oldFullName", oldFullName);
                    p.AddWithValue("newFullName", org.FullName);
                    p.AddWithValue("orgId", org.Id);
                    db.Execute(sql, p);

                    // 记录操作日志
                    new LogService().Log("编辑组织机构：" + org.ToString());
                });
            }

            return result;
        }

        public Models.Org GetOrg(string id)
        {
            var sql = "select org_name, org_full_name, parent_id, org_code from psi_org where org_id = @orgId";
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();
            p.AddWithValue("orgId", id);
            var result = new Models.Org();
            db.Query(sql, reader => {
                result.Id = id;
                result.Name = reader.GetString(0);
                result.FullName = reader.GetString(1);
                result.ParentId = reader.GetString(2);
                result.OrgCode = reader.GetString(3);
            }, p);

            sql = "select org_name from psi_org where org_id = @orgId";
            p = db.CreateDbParameters();
            p.AddWithValue("orgId", result.ParentId);
            db.Query(sql, reader => {
                result.ParentOrgName = reader.GetString(0);
            }, p);

            return result;
        }

        public Result DeleteOrg(string id) {
            var db = DBHelper.AdoTemplate;

            // 检查当前组织机构是否有人员
            var sql = "select count(*) from psi_user where org_id = @orgId";
            var p = db.CreateDbParameters();
            p.AddWithValue("orgId", id);
            var count = db.QueryCount(sql, p);
            if (count > 0) {
                return new Result { Success = false, Messgae = "当前组织机构还有人员，不能删除" };
            }

            // 检查当前组织机构是否有下级机构
            sql = "select count(*) from psi_org where parent_id = @parentId";
            p = db.CreateDbParameters();
            p.AddWithValue("parentId", id);
            count = db.QueryCount(sql, p);
            if (count > 0) {
                return new Result { Success = false, Messgae = "当前组织机构还有下级机构，不能删除" };
            }

            // 判断can_delete标记
            sql = "select can_delete from psi_org where org_id = @orgId";
            p = db.CreateDbParameters();
            p.AddWithValue("orgId", id);
            var canDelete = db.QueryObject<string>(sql, reader => { return reader.GetString(0); }, p);

            if (canDelete != "0000000000") // 10个0
            {
                return new Result { Success = false, Messgae = "当前组织机构已经启用，不能删除" };
            }

            DBHelper.TransactionTemplate.WithTransaction(() => {
                sql = "select org_name, org_full_name, org_code from psi_org where org_id = @orgId";
                p = db.CreateDbParameters();
                p.AddWithValue("orgId", id);
                var orgToDelete = new Models.Org { Id = id };
                db.Query(sql, reader => {
                    orgToDelete.Name = reader.GetString(0);
                    orgToDelete.FullName = reader.GetString(1);
                    orgToDelete.OrgCode = reader.GetString(2);
                }, p);

                sql = "delete from psi_org where org_id = @orgId";
                p = db.CreateDbParameters();
                p.AddWithValue("orgId", id);
                db.Execute(sql, p);

                // 记录操作日志
                new LogService().Log("删除组织机构： " + orgToDelete.ToString());
            });

            return new Result { Success = true };
        }

        public Result EditUser(User user) {
            if (string.IsNullOrEmpty(user.Id)) {
                // 新增

                // 检查LoginName是否已经存在
                var db = DBHelper.AdoTemplate;
                var p = db.CreateDbParameters();
                var sql = "select count(*) from psi_user where login_name = @loginName";
                p.AddWithValue("loginName", user.LoginName);
                var count = db.QueryCount(sql, p);

                if (count != 0) {
                    return new Result { Success = false, Messgae = "登录名 " + user.LoginName + " 已经存在" };
                }

                user.Id = IdGeneratorService.NewId();
                sql = @"insert into psi_user(user_id, login_name, user_name,tel, password, org_id, enabled, org_code, can_delete)
                            values (@userId, @loginName, @userName,@tel, @password, @orgId, @enabled, @orgCode, @canDelete)";
                p = db.CreateDbParameters();
                p.AddWithValue("userId", user.Id);
                p.AddWithValue("loginName", user.LoginName);
                p.AddWithValue("userName", user.Name);
                p.AddWithValue("password", SimpleCrypt.Encode("123456")); // 默认密码为123456
                p.AddWithValue("orgId", user.OrgId);
                p.AddWithValue("tel", user.Tel);
                p.AddWithValue("enabled", user.Enabled ? 1 : 0);
                p.AddWithValue("orgCode", user.OrgCode);
                p.AddWithValue("canDelete", "0000000000"); // 十个0

                db.Execute(sql, p);

                new LogService().Log("新增用户: " + user.ToString());
            } else {
                // 编辑

                // 检查loginName是否已经被使用
                var sql = "select count(*) from psi_user where login_name = @loginName and user_id <> @userId";
                var db = DBHelper.AdoTemplate;
                var p = db.CreateDbParameters();
                p.AddWithValue("loginName", user.LoginName);
                p.AddWithValue("userId", user.Id);

                var count = db.QueryCount(sql, p);
                if (count > 0) {
                    return new Result {
                        Success = false,
                        Messgae = "登录名 " + user.LoginName + " 已经被其他用户使用"
                    };
                }

                sql = @"update psi_user 
                            set user_name = @userName, org_id = @orgId, 
                                enabled = @enabled, org_code = @orgCode,tel=@tel
                        where user_id = @userId";
                p = db.CreateDbParameters();
                p.AddWithValue("userName", user.Name);
                p.AddWithValue("orgId", user.OrgId);
                p.AddWithValue("enabled", user.Enabled ? 1 : 0);
                p.AddWithValue("tel", user.Tel);
                p.AddWithValue("orgCode", user.OrgCode);
                p.AddWithValue("userId", user.Id);

                db.Execute(sql, p);

                new LogService().Log("编辑用户:" + user.ToString());
            }

            return new Result { Success = true };
        }

        public Result DeleteUser(string id) {
            var sql = "select can_delete from psi_user where user_id = @userId";
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();
            p.AddWithValue("userId", id);
            var canDelete = db.QueryObject<string>(sql,
                reader => {
                    return reader.GetString(0);
                }, p);

            if (canDelete != "0000000000") // 10个0
            {
                return new Result { Success = false, Messgae = "当前用户已经启用，不能删除" };
            }

            var user = GetUser(id);

            sql = "delete from psi_user where user_id = @userId";
            p = db.CreateDbParameters();
            p.AddWithValue("userId", id);
            db.Execute(sql, p);

            new LogService().Log("删除用户: " + user.ToString());

            return new Result { Success = true };
        }

        public User GetUser(string userId) {
            var user = new User();

            var sql = "select login_name, user_name, enabled, org_code,tel from psi_user where user_id = @userId";
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();
            p.AddWithValue("userId", userId);
            db.Query(sql, reader => {
                user.Id = userId;
                user.LoginName = reader.GetString(0);
                user.Name = reader.GetString(1);
                user.Enabled = reader.GetInt32(2) == 1;
                user.OrgCode = reader.GetString(3);
                user.Tel = reader.GetString(4);
            }, p);

            return user;
        }

        public Result ChangePassword(string userId, string password) {
            if (string.IsNullOrEmpty(password)) {
                return new Result { Success = false, Messgae = "密码不能为空" };
            }

            var sql = "update psi_user set password = @password where user_id = @userId";
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();
            p.AddWithValue("userId", userId);
            p.AddWithValue("password", SimpleCrypt.Encode(password));
            db.Execute(sql, p);

            var user = GetUser(userId);
            new LogService().Log("修改用户密码，该用户是: " + user.ToString());

            return new Result { Success = true };
        }

        public Result ChangeMyPassword(string userId, string oldPassword, string newPassword) {
            var sql = "select count(*) from psi_user where user_id = @userId and password = @password";
            var db = DBHelper.AdoTemplate;
            var p = db.CreateDbParameters();
            p.AddWithValue("userId", userId);
            p.AddWithValue("password", SimpleCrypt.Encode(oldPassword));

            var count = db.QueryCount(sql, p);

            if (count != 1) {
                return new Result { Success = false, Messgae = "旧密码错误" };
            }

            sql = "update psi_user set password = @password where user_id = @userId";
            p = db.CreateDbParameters();
            p.AddWithValue("userId", userId);
            p.AddWithValue("password", SimpleCrypt.Encode(newPassword));
            db.Execute(sql, p);

            var u = UserService.GetLoginUser();
            u.Password = newPassword;
            SetLoginUser(u);
            return new Result { Success = true };
        }
    }
}